/*
 * Menu.cpp
 *
 *  Created on: May 3, 2010
 *      Author: rneal2
 */

#include "Menu.h"
#include "config.h"

Menu::Menu(WineryManager *mgr): tour(),manager(mgr), password("default"){
}
Menu::Menu(WineryTour *tour, WineryManager *mgr, string p)
	 :tour(tour),manager(mgr), password(p){
}

void Menu::MainMenu()
{
	int choice;
	bool exit;
	exit = false;

	do
	{
		cout << endl;
		cout <<	"====================================" << endl;
		cout <<	"*             MAIN MENU            *" << endl;
		cout <<	"*----------------------------------*" << endl;
		cout <<	"* 1) View our list of wineries     *" << endl;
		cout <<	"* 2) Plan a day trip               *" << endl;
		cout <<	"* 3) Tour your wineries            *" << endl;
		cout <<	"* 4) Maintenance (admin only)      *" << endl;
		cout <<	"* 0) Exit program                  *" << endl;
		cout <<	"====================================" << endl;
		cout << "Enter your option (0-4): ";

		cin >> choice;
		switch(choice)
		{
			case(0):exit = true;
					break;
			case(1)://calls function to print list of wineries
					manager->DisplayWineries();
					break;
			case(2):Menu::TripMenu();
					break;
			case(3):if(tour->IsEmpty(tour->GetWineryList()))
						cout << "You must schedule a tour first" << endl;
					else
						tour->TakeTour();
					break;
			case(4):Menu::PasswordProtect();
					break;
			default:cout << "Improper input, try again." << endl;
					break;
		}
	}while(exit == false);
}

void Menu::TripMenu()
{
	int choice;
	bool exit;
	exit = false;

	do
	{
		cout << endl;
		cout <<	"====================================" << endl;
		cout <<	"*            TRIP MENU             *" << endl;
		cout <<	"*----------------------------------*" << endl;
		cout <<	"* 1) Generate shortest trip        *" << endl;
		cout <<	"* 2) Plan a custom trip            *" << endl;
		cout <<	"* 0) Main menu                     *" << endl;
		cout <<	"====================================" << endl;
		cout << "Enter your option (0-2): ";

		cin >> choice;
		switch(choice)
		{
			case(0):exit = true;
					break;
			case(1):AutoTrip();
					break;
			case(2):CustomTrip();
					break;
			default:cout << "Improper input, try again." << endl;
					break;
		}
	}while(exit == false);
}

void Menu::AdminMenu()
{
	int choice, wineryId;
	Winery *w;
	bool exit;
	exit = false;

	do
	{
		cout << endl;
		cout <<	"====================================" << endl;
		cout <<	"*         FILE MAINTENANCE         *" << endl;
		cout <<	"*----------------------------------*" << endl;
		cout <<	"* 1) Add new winery                *" << endl;
		cout <<	"* 2) Edit winery                   *" << endl;
		cout <<	"* 3) Change password               *" << endl;
		cout << "* 4) Import wineries               *" << endl;
		cout << "* 5) Reset winery list             *" << endl;
		cout <<	"* 0) Main menu                     *" << endl;
		cout <<	"====================================" << endl;
		cout << "Enter your option (0-5): ";

		cin >> choice;
		switch(choice)
		{
			case(0):exit = true;
					break;
			case(1):Menu::NewWinery();
					break;
			case(2):
				for (int k = 1; k <= manager->GetNumWineries(); k++) {
					Winery *tmp = manager->GetWinery(k);
					cout << k << ". " << tmp->GetName() << endl;
					delete tmp;
				}
				cout << "Enter ID of winery to edit: ";
				cin >> wineryId;
				cin.ignore(100, '\n');
				w = manager->GetWinery(wineryId);
				EditWinery(w);
				break;
			case(3):Menu::SetPassword();
					break;
			case(4):Menu::ImportWineries();
					break;
			case(5):
				manager->ResetWineries();
				cout << "Winery list reset" << endl;
				break;
			default:cout << "Improper input, try again." << endl;
					break;
		}
	}while(exit == false);
}

void Menu::NewWinery()
{
	Winery *winery;
	Wine wine;
	int newWineryId;
	int choice;
	bool exit;
	char name[MAX_NAME_LENGTH];
	exit = false;

	newWineryId = manager->GetNumWineries() + 1;
	winery = new Winery(newWineryId);

	do
	{
		cout << endl;
		cout <<	"====================================" << endl;
		cout <<	"*            NEW WINERY            *" << endl;
		cout <<	"*----------------------------------*" << endl;
		cout <<	"* 1) Name of winery                *" << endl;
		cout <<	"* 2) Distance to other wineries    *" << endl;
		cout <<	"* 3) Add an available wine         *" << endl;
		cout <<	"* 0) Save and exit                 *" << endl;
		cout <<	"====================================" << endl;
		cout << "Enter your option (0-3): ";

		cin >> choice;
		switch(choice)
		{
			case(0):exit = true;
					break;
			case(1):cout << "Name: ";
					cin.ignore(100,'\n');
					cin.getline(name,MAX_NAME_LENGTH);
					winery->SetName(name);
					break;
			case(2):
					InputWineryDistances(winery);
					break;
			case(3):
				wine = InputWine();
				winery->AddWine(wine);
				break;
			default:cout << "Improper input, try again." << endl;
					break;
		}
	}while(exit == false);

	manager->SaveWinery(winery, newWineryId);
	cout << "Saved winery" << endl;

}

void Menu::InputWineryDistances(Winery *w) {
	Winery *inWinery;
	int numWineries, i;
	float dist;

	numWineries = manager->GetNumWineries();
	for (i = 1; i <= numWineries; i++) {
		inWinery = manager->GetWinery(i);
		cout << "Enter distance to ";
		cout << inWinery->GetName() << ": ";
		cin >> dist;
		w->SetDistanceToWinery(i, dist);
		delete inWinery;
	}
}

Wine Menu::InputWine() {
	Wine w;
	cout << "Wine Name: ";
	cin.ignore(100, '\n');
	cin.getline(w.wineName, MAX_NAME_LENGTH);
	cout << "Price: ";
	cin >> w.price;
	cin.ignore(100, '\n');
	cout << "Vintage: ";
	cin >> w.vintage;
	cin.ignore(100, '\n');
	return w;
}

void Menu::EditWinery(Winery *winery) {
	Wine wine;
	int newWineryId;
	int choice;
	bool exit;
	char name[MAX_NAME_LENGTH];
	exit = false;

	newWineryId = winery->GetId();

	do
	{
		cout << endl;
		cout <<	"====================================" << endl;
		cout <<	"*            EDIT WINERY           *" << endl;
		cout <<	"*----------------------------------*" << endl;
		cout <<	"* 1) Name of winery                *" << endl;
		cout <<	"* 2) Distance to other wineries    *" << endl;
		cout <<	"* 3) Add an available wine         *" << endl;
		cout <<	"* 0) Save and exit                 *" << endl;
		cout <<	"====================================" << endl;
		cout << "Enter your option (0-3): ";

		cin >> choice;
		switch(choice)
		{
			case(0):exit = true;
					break;
			case(1):
					cout << "Current name: " << winery->GetName() << endl;
					cout << "Enter a new name: ";
					cin.ignore(100,'\n');
					cin.getline(name,MAX_NAME_LENGTH);
					winery->SetName(name);
					break;
			case(2):
					InputWineryDistances(winery);
					break;
			case(3):
				wine = InputWine();
				winery->AddWine(wine);
				break;
			default:cout << "Improper input, try again." << endl;
					break;
		}
	}while(exit == false);

	manager->SaveWinery(winery, newWineryId);
	cout << "Saved winery" << endl;
}

void Menu::NewWine()
{
	Winery *winery;
	Wine wine;
	int choice;
	int id;
	bool exit;
	exit = false;

	winery = manager->GetWinery(id);


	do
	{
		cout << endl;
		cout <<	"====================================" << endl;
		cout <<	"*             NEW WINE             *" << endl;
		cout <<	"*----------------------------------*" << endl;
		cout <<	"* 1) Add new wine                  *" << endl;
		cout <<	"* 0) Admin menu                    *" << endl;
		cout <<	"====================================" << endl;
		cout << "Enter your option (0-1): ";

		cin >> choice;
		switch(choice)
		{
			case(0):exit = true;
					break;
			case(1):cout << "Name: ";
					cin.getline(wine.wineName,MAX_NAME_LENGTH);
					cout << "Vintage: ";
					cin >> wine.vintage;
					cout << "Price: ";
					cin >> wine.price;
					winery->AddWine(wine);
				    break;
			default:cout << "Improper input, try again." << endl;
					break;
		}
	}while(exit == false);
}

void Menu::AutoTrip()
{
	int choice;
	int id;
	float dist;
	Winery *winery;
	vector<Winery> wineryList;
	bool valid, exit;

	dist = 0.0;
	valid = true;
	exit = false;

	cout << endl;
	cout <<	"=========================================" << endl;
	cout <<	"*               Auto Trip               *" << endl;
	cout <<	"*---------------------------------------*" << endl;
	for(int i = 1; i <= manager->GetNumWineries(); i++)
	{
		winery = manager->GetWinery(i);
		cout << '*' << setfill(' ') << setw(2) << right << i << ") " << left;
		cout << setw(35) << winery->GetName() << '*' << endl;
	}
	cout <<	"* 0) Trip menu                          *" << endl;
	cout <<	"=========================================" << endl;
	do
	{
		valid = true;
		cout << "Enter your option (0-" << manager->GetNumWineries() <<"): ";
		cin >> choice;
		if(choice <= manager->GetNumWineries() && choice > 0)
		{
			valid = true;
			exit = false;
		}
		else if(choice == 0)
		{
			valid = true;
			exit = true;
		}
		else
		{
			cout << "Improper input, try again." << endl;
			valid = false;
			exit = false;
		}
	}while(!valid);

	valid = false;
	winery = manager->GetWinery(choice);
	tour->AddWineryToList(*winery);

	while(!exit && !valid)
	{
		cout << "How many wineries would you like to visit?";
		cout << "(1-" << manager->GetNumWineries() <<"): ";
		cin >> choice;
		if(choice <= manager->GetNumWineries() && choice > 0)
			valid = true;
		else
			cout << "Improper input, try again." << endl;
	}

	for(int i = 1; i < choice; i++)
	{
		wineryList = tour->GetWineryList();

		dist = 0.0;

		for(int f = 1; f <= manager->GetNumWineries(); f++)
		{
			valid = true;
			for(int t = 0; t < i; t++)
			{
				if(f == wineryList[t].GetId())
					valid = false;
			}
			if (!valid) {
				continue;
			}

			if(wineryList[i-1].GetDistanceToWinery(f) <= dist
					|| dist < 0.01)
			{
				dist = wineryList[i-1].GetDistanceToWinery(f);
				id = f;
			}
		}
		winery = manager->GetWinery(id);
		tour->AddWineryToList(*winery);
	}
}

void Menu::CustomTrip()
{
	int choice;
	Winery *winery;
	vector<Winery> wineryList;
	bool valid, exit;

	exit = false;

	do
	{
		wineryList = tour->GetWineryList();
		cout << endl;
		cout <<	"===============================================" << endl;
		cout <<	"*                 Custom Trip                 *" << endl;
		cout <<	"*---------------------------------------------*" << endl;
		cout <<	"* ID             Name               Distance  *" << endl;
		cout <<	"*---------------------------------------------*" << endl;
		for(int i = 1; i <= manager->GetNumWineries(); i++)
		{
			valid = true;
			winery = manager->GetWinery(i);
			for(unsigned int t = 0; t < wineryList.size(); t++)
			{
				if(i == wineryList[t].GetId())
					valid = false;
			}
			if(valid)
			{
				cout << '*' << setw(2) << right << winery->GetId() << ") ";
				cout << left << setw(35) << winery->GetName()<<' '<<setw(5);
				if(tour->IsEmpty(tour->GetWineryList()))
					cout << winery->GetDistance() << "*\n";
				else
					cout << winery->GetDistanceToWinery(i) << "*\n";
			}
		}
		cout <<	"* 0) Trip menu                                *" << endl;
		cout <<	"*---------------------------------------------*" << endl;
		do
		{
			cout << "Enter the ID of the next winery (0 to exit): ";
			cin >> choice;
			valid = true;
			if(choice > manager->GetNumWineries() || choice < 0)
			{
				cout << "Improper input, try again." << endl;
				valid = false;
			}
			else if(choice == 0)
				exit = true;
		}while(!valid);
		if(!exit)
		{
			winery = manager->GetWinery(choice);
			tour->AddWineryToList(*winery);
		}
	}while(!exit);
}

void Menu::PasswordProtect()
{
	string inputPass;

	cout << endl;
	cout <<	"====================================" << endl;
	cout <<	"*     ADMINISTRATOR PASSWORD       *" << endl;
	cout <<	"====================================" << endl;
	cout <<	"Enter your password: ";
	cin.ignore(100,'\n');
	getline(cin, inputPass);

	if(inputPass == password)
		Menu::AdminMenu();
	else
		cout << endl << "Password incorrect.";
}

void Menu::ImportWineries()
{
	string fileName;
	const char *defaultFileName = WT_WINERY_DEFAULT_IMPORT_FILE;

	cout << endl;
	cout <<	"====================================" << endl;
	cout << "*        IMPORT WINERIES           *" << endl;
	cout <<	"====================================" << endl;
	cout << "Enter filename: [" << defaultFileName << "] ";
	cin.ignore(100, '\n');
	getline(cin, fileName);
	if (fileName.length() < 3) {
		fileName = string(defaultFileName);
	}

	if (manager->ImportWineries(fileName.c_str())) {
		cout << endl << "Successfully imported wineries.";
	} else {
		cout << endl << "Error with import.";
	}
}

void Menu::SetPassword()
{
	string inputPass;

	cout << endl;
	cout <<	"====================================" << endl;
	cout <<	"*          CHANGE PASSWORD         *" << endl;
	cout <<	"====================================" << endl;
	cout <<	"Enter your new password: ";
	cin.ignore(100,'\n');
	getline(cin, inputPass);
	password = inputPass;
}
